import apiClient from './client'
import type { AxiosProgressEvent } from 'axios'

// 文件类型
export type FileStatus = 'UPLOADING' | 'UPLOADED' | 'PROCESSING' | 'READY' | 'EXPIRED' | 'DELETED'
export type FileCategory = 'IMAGE' | 'VIDEO' | 'AUDIO' | 'DOCUMENT' | 'ARCHIVE' | 'OTHER'

// 接口定义
export interface FileInfo {
  id: string
  originalName: string
  storedName: string
  mimeType: string
  size: number
  extension?: string
  url: string
  thumbnailUrl?: string
  uploaderId: string
  uploaderName?: string
  conversationId?: string
  messageId?: string
  status: FileStatus
  category: FileCategory
  downloadCount: number
  expiresAt?: string
  metadata?: Record<string, any>
  createdAt: string
}

export interface FileUploadResponse {
  id: string
  originalName: string
  url: string
  thumbnailUrl?: string
  mimeType: string
  size: number
  category: FileCategory
  md5Hash?: string
  createdAt: string
}

export interface InitChunkUploadRequest {
  fileName: string
  fileSize: number
  chunkSize: number
  md5Hash?: string
}

export interface InitChunkUploadResponse {
  uploadId: string
  chunkSize: number
  totalChunks: number
  existingFile?: FileUploadResponse
}

export interface ChunkUploadStatus {
  uploadId: string
  fileName: string
  totalChunks: number
  uploadedChunks: number[]
  progress: number
  status: string
}

export interface StorageUsage {
  totalSize: number
  fileCount: number
  byCategory: Record<FileCategory, { count: number, size: number }>
  quota: number
  usagePercentage: number
}

// 文件API
export const fileAPI = {
  // 上传文件
  uploadFile: (
    file: File,
    conversationId?: string,
    messageId?: string,
    onProgress?: (progress: number) => void
  ): Promise<FileUploadResponse> => {
    const formData = new FormData()
    formData.append('file', file)
    if (conversationId) formData.append('conversationId', conversationId)
    if (messageId) formData.append('messageId', messageId)

    return apiClient.post('/files/upload', formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      },
      onUploadProgress: (progressEvent: AxiosProgressEvent) => {
        if (onProgress && progressEvent.total) {
          const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)
          onProgress(percentCompleted)
        }
      }
    })
  },

  // 初始化分片上传
  initChunkUpload: (request: InitChunkUploadRequest): Promise<InitChunkUploadResponse> => {
    return apiClient.post('/files/chunk/init', request)
  },

  // 上传分片
  uploadChunk: (
    uploadId: string,
    chunkIndex: number,
    chunk: Blob
  ): Promise<ChunkUploadStatus> => {
    const formData = new FormData()
    formData.append('uploadId', uploadId)
    formData.append('chunkIndex', chunkIndex.toString())
    formData.append('chunk', chunk)

    return apiClient.post('/files/chunk/upload', formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    })
  },

  // 完成分片上传
  completeChunkUpload: (
    uploadId: string,
    conversationId?: string,
    messageId?: string
  ): Promise<FileUploadResponse> => {
    return apiClient.post('/files/chunk/complete', null, {
      params: { uploadId, conversationId, messageId }
    })
  },

  // 下载文件
  downloadFile: (fileId: string): Promise<Blob> => {
    return apiClient.get(`/files/${fileId}/download`, {
      responseType: 'blob'
    })
  },

  // 删除文件
  deleteFile: (fileId: string): Promise<void> => {
    return apiClient.delete(`/files/${fileId}`)
  },

  // 获取我的文件列表
  getMyFiles: (
    category?: FileCategory,
    page: number = 0,
    size: number = 20
  ): Promise<{ files: FileInfo[], hasMore: boolean, total: number }> => {
    return apiClient.get('/files/my-files', {
      params: { category, page, size }
    })
  },

  // 获取存储使用统计
  getStorageUsage: (): Promise<StorageUsage> => {
    return apiClient.get('/files/storage-usage')
  }
}

// 文件上传辅助函数
export class FileUploader {
  private chunkSize: number = 5 * 1024 * 1024 // 5MB

  async uploadLargeFile(
    file: File,
    onProgress?: (progress: number) => void,
    conversationId?: string,
    messageId?: string
  ): Promise<FileUploadResponse> {
    // 计算MD5（可选）
    // const md5Hash = await this.calculateMD5(file)

    // 初始化分片上传
    const initResponse = await fileAPI.initChunkUpload({
      fileName: file.name,
      fileSize: file.size,
      chunkSize: this.chunkSize
      // md5Hash
    })

    // 如果文件已存在（秒传）
    if (initResponse.existingFile) {
      onProgress?.(100)
      return initResponse.existingFile
    }

    // 上传所有分片
    const totalChunks = initResponse.totalChunks
    for (let i = 0; i < totalChunks; i++) {
      const start = i * this.chunkSize
      const end = Math.min(start + this.chunkSize, file.size)
      const chunk = file.slice(start, end)

      await fileAPI.uploadChunk(initResponse.uploadId, i, chunk)

      onProgress?.(Math.round(((i + 1) / totalChunks) * 100))
    }

    // 完成上传
    return await fileAPI.completeChunkUpload(
      initResponse.uploadId,
      conversationId,
      messageId
    )
  }

  private async calculateMD5(file: File): Promise<string> {
    // TODO: 实现MD5计算
    return ''
  }
}
